﻿using System;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal struct Ref8U
    {
        private ushort colFirst, colLast;
        private ushort rwFirst, rwLast;

        public const int Size = 8;
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (obj.GetType() != typeof (Ref8U)) return false;
            return Equals((Ref8U) obj);
        }

        public static explicit operator RangeAddress(Ref8U address)
        {
            Contract.Ensures(((Ref8U) Contract.Result<RangeAddress>()).Equals(address));
            return new RangeAddress(new CellAddress(address.rwFirst, address.colFirst),
                                    new CellAddress(address.rwLast, address.colLast));
        }

        public static explicit operator Ref8U(RangeAddress address)
        {
            return new Ref8U
                       {
                           rwFirst = (ushort) address.TopLeft.Row,
                           rwLast = (ushort) address.BottomRight.Row,
                           colFirst = (ushort) address.TopLeft.Column,
                           colLast = (ushort) address.BottomRight.Column
                       };
        }

        public void Read(BinaryReader reader)
        {
            rwFirst = reader.ReadUInt16();
            rwLast = reader.ReadUInt16();
            colFirst = reader.ReadUInt16();
            colLast = reader.ReadUInt16();
        }

        public void Write(BinaryWriter writer)
        {
            writer.Write(rwFirst);
            writer.Write(rwLast);
            writer.Write(colFirst);
            writer.Write(colLast);
        }

        public bool Equals(Ref8U other)
        {
            return other.colFirst == colFirst && other.colLast == colLast && other.rwFirst == rwFirst && other.rwLast == rwLast;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int result = colFirst.GetHashCode();
                result = (result*397) ^ colLast.GetHashCode();
                result = (result*397) ^ rwFirst.GetHashCode();
                result = (result*397) ^ rwLast.GetHashCode();
                return result;
            }
        }
    }
}